﻿using System;
using System.Text.RegularExpressions;
using System.Collections;
using System.Collections.Generic;

namespace Domain.Repository
{
    public class CommonTools
    {
        private CommonTools() { }

        private static IDictionary<string, Type> _modelTypes;

        public static void AddModel(Type type)
        {
            if (null == _modelTypes)
            {
                _modelTypes = new Dictionary<string, Type>();
            }
            _modelTypes.Add(type.FullName, type);
        }

        public static Type GetModelType(string fullName)
        {
            if (String.IsNullOrWhiteSpace(fullName)||!_modelTypes.ContainsKey(fullName))
            {
                return null;
            }
            return _modelTypes[fullName];
        }

        public static string ReplaceHtml(string html)
        {
            if (String.IsNullOrWhiteSpace(html))
            {
                return null;
            }
            Regex regex = new Regex("<(.|\n)+?>");
            string result = regex.Replace(html, String.Empty);
            //&lt;p&gt;
            regex = new Regex("&lt;(.|\n)+?&gt;");
            result = regex.Replace(result, String.Empty);
            regex = new Regex("&(.+?);");
            result = regex.Replace(result, String.Empty);
            return result;
        }

        public static IList<T> Sort<T>(ICollection<T> entries)
        {
            if (null == entries)
            {
                return null;
            }
            List<T> instances = new List<T>();
            foreach (T item in entries)
            {
                instances.Add(item);
            }
            instances.Sort();
            return instances;
        }

        public static string UniqueIDFromString(string str)
        {
            System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] bytes = System.Text.Encoding.UTF8.GetBytes(str);
            bytes = md5.ComputeHash(bytes);
            md5.Clear();

            string result = ("EXTID" + Convert.ToBase64String(bytes)
                    .Replace('+', '-')
                    .Replace('/', '_')
                    .Replace("=", String.Empty)).PadRight(32, 'K').ToLower();
            return result;
        }


        private static Regex RegNumber = new Regex("^[0-9]+$");
        private static Regex RegNumberSign = new Regex("^[+-]?[0-9]+$");
        private static Regex RegDecimal = new Regex("^[0-9]+[.]?[0-9]+$");
        private static Regex RegDecimalSign = new Regex("^[+-]?[0-9]+[.]?[0-9]+$"); //等价于^[+-]?\d+[.]?\d+$
        private static Regex RegEmail = new Regex("^[\\w-]+@[\\w-]+\\.(com|net|org|edu|mil|tv|biz|info)$");//w 英文字母或数字的字符串，和 [a-zA-Z0-9] 语法一样 
        //private static Regex RegCHZN = new Regex(@"[\一-\龥]");


        /// <summary>
        /// 对入库字符进行编码和转换
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string EncodeStr(string str)
        {
            str = str.Replace("'", "’");
            str = str.Replace("\"", "&quot;");
            str = str.Replace("<", "&lt;");
            str = str.Replace(">", "&gt;");
            str = str.Replace("\n", "<br>");
            return str;
        }

        /// <summary>
        /// 对出库字符进入显示时的转换
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string DecodeStr(string str)
        {
            str = str.Replace("’", "'");
            str = str.Replace("&quot;", "\"");
            str = str.Replace("&lt;", "<");
            str = str.Replace("&gt;", ">");
            str = str.Replace("<br>", "\n");
            return str;
        }

        /// <summary>
        /// 是否数字字符串
        /// </summary>
        /// <param name="inputData">输入字符串</param>
        /// <returns></returns>
        public static bool IsNumber(string inputData)
        {
            Match m = RegNumber.Match(inputData);
            return m.Success;
        }

        /// <summary>
        /// 是否数字字符串 可带正负号
        /// </summary>
        /// <param name="inputData">输入字符串</param>
        /// <returns></returns>
        public static bool IsNumberSign(string inputData)
        {
            Match m = RegNumberSign.Match(inputData);
            return m.Success;
        }

        /// <summary>
        /// 是否是浮点数
        /// </summary>
        /// <param name="inputData">输入字符串</param>
        /// <returns></returns>
        public static bool IsDecimal(string inputData)
        {
            Match m = RegDecimal.Match(inputData);
            return m.Success;
        }

        /// <summary>
        /// 是否是浮点数 可带正负号
        /// </summary>
        /// <param name="inputData">输入字符串</param>
        /// <returns></returns>
        public static bool IsDecimalSign(string inputData)
        {
            Match m = RegDecimalSign.Match(inputData);
            return m.Success;
        }


        /// <summary>
        /// 非法字符转换
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string ReplaceStr(string str)
        {
            str = str.Replace(",", String.Empty);
            str = str.Replace("'", String.Empty);
            str = str.Replace(";", String.Empty);
            str = str.Replace(":", String.Empty);
            str = str.Replace("/", String.Empty);
            str = str.Replace("?", String.Empty);
            str = str.Replace("<", String.Empty);
            str = str.Replace(">", String.Empty);
            str = str.Replace(".", String.Empty);
            str = str.Replace("#", String.Empty);
            str = str.Replace("%", String.Empty);
            str = str.Replace("%", String.Empty);
            str = str.Replace("^", String.Empty);
            str = str.Replace("//", String.Empty);
            str = str.Replace("@", String.Empty);
            str = str.Replace("(", String.Empty);
            str = str.Replace(")", String.Empty);
            str = str.Replace("*", String.Empty);
            str = str.Replace("~", String.Empty);
            str = str.Replace("`", String.Empty);
            str = str.Replace("$", String.Empty);

            return str;
        }


        /// <summary>
        /// 检查url
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool CheckURl(string str)
        {
            Regex r = new Regex("^http://([\\w-]+\\.)+[\\w-]+(/[\\w-./?%&=]*)?$");

            Match m = r.Match(str);
            if (m.Success)
            {
                return true;
            }
            else
            {
                return false;
            }

        }



        /// <summary>
        /// 日期格式检查
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool CheckDateFormat(string str)
        {

            Regex r = new Regex("^(\\d{4})\\-(\\d{2})\\-(\\d{2})$");
            Match m = r.Match(str);

            if (m.Success)
            {
                return true;
            }
            else
            {
                return false;

            }

        }

        /// <summary>
        /// 日期有效性检查 ^(\\d{4})\\-(\\d{2})\\-(\\d{2})$
        /// <br />
        /// 检查年月日是否都在有效的范围
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool CheckDateValidity(string str)
        {
            Regex r = new Regex("^(\\d{4})\\-(\\d{2})\\-(\\d{2})$");
            Match m = r.Match(str);
            if (m.Success)  //格式正确
            {
                string M = m.ToString();
                char[] da = new char[10];//char.Parse(m.ToString());

                M.CopyTo(0, da, 0, 10);

                bool bl = false;
                string yy = "";
                string mm = "";
                string dd = "";

                #region 分别取出 YYYY、MM、DD
                for (int i = 0; i < 4; i++)
                {
                    yy += da[i].ToString();
                }

                for (int i = 0; i < 2; i++)
                {
                    mm += da[5 + i].ToString();
                }

                for (int i = 0; i < 2; i++)
                {
                    dd += da[8 + i].ToString();
                }
                #endregion

                int YearLow = DateTime.MinValue.Year;
                int YearHigh = DateTime.MaxValue.Year;
                if (int.Parse(yy) < YearHigh && int.Parse(yy) > YearLow)  //
                {
                    #region  是否为有效的日期值
                    bool b = true;
                    if (b)
                    {
                        bool B = false;
                        switch (mm)
                        {
                            case "01": B = true;
                                break;
                            case "02": B = true;
                                break;
                            case "03": B = true;
                                break;
                            case "04": B = true;
                                break;
                            case "05": B = true;
                                break;
                            case "06": B = true;
                                break;
                            case "07": B = true;
                                break;
                            case "08": B = true;
                                break;
                            case "09": B = true;
                                break;
                            case "10": B = true;
                                break;
                            case "11": B = true;
                                break;
                            case "12": B = true;
                                break;
                        }
                        if (B)
                        {
                            switch (dd)
                            {
                                case "01": bl = true;
                                    break;
                                case "02": bl = true;
                                    break;
                                case "03": bl = true;
                                    break;
                                case "04": bl = true;
                                    break;
                                case "05": bl = true;
                                    break;
                                case "06": bl = true;
                                    break;
                                case "07": bl = true;
                                    break;
                                case "08": bl = true;
                                    break;
                                case "09": bl = true;
                                    break;
                                case "10": bl = true;
                                    break;
                                case "11": bl = true;
                                    break;
                                case "12": bl = true;
                                    break;
                                case "13": bl = true;
                                    break;
                                case "14": bl = true;
                                    break;
                                case "15": bl = true;
                                    break;
                                case "16": bl = true;
                                    break;
                                case "17": bl = true;
                                    break;
                                case "18": bl = true;
                                    break;
                                case "19": bl = true;
                                    break;
                                case "20": bl = true;
                                    break;
                                case "21": bl = true;
                                    break;
                                case "22": bl = true;
                                    break;
                                case "23": bl = true;
                                    break;
                                case "24": bl = true;
                                    break;
                                case "25": bl = true;
                                    break;
                                case "26": bl = true;
                                    break;
                                case "27": bl = true;
                                    break;
                                case "28": bl = true;
                                    break;
                                case "29": bl = true;
                                    break;
                                case "30": bl = true;
                                    break;
                                case "31": bl = true;
                                    break;
                            }
                        }
                    }
                    #endregion
                }
                else
                {
                    bl = false;
                }

                if (bl)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                return false;
            }

        }
    }
}
